﻿using Lynn.Infastructure.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace Lynn.Infastructure.Net.Http
{
    public class HttpWork
    {
        HttpOption _option;
        HttpClient _client;
        IHttpClientFactory _httpClientFactory;
        public HttpWork(IHttpClientFactory httpClientFactory,HttpOption option)
        {
            _option = option;
            _httpClientFactory = httpClientFactory;
            _client = _httpClientFactory.CreateClient(_option.DefaultName);
        }
        public HttpWork AddHeader(string name, string value) {
            _client.DefaultRequestHeaders.Add(name, value);
            return this;
        }
        public HttpWork AddHeader(string name, IEnumerable<string> values)
        {
            _client.DefaultRequestHeaders.Add(name, values);
            return this;
        }
        public HttpWork AddHeader(Dictionary<string,string> headers)
        {
            foreach (var dic in headers) {
                _client.DefaultRequestHeaders.Add(dic.Key,dic.Value);
            }
            return this;
        }
        public HttpWork UseName(string name)
        {
            _client = _httpClientFactory.CreateClient(name);
            return this;
        }
        public async Task<string> PostJson<TValue>(TValue body, string url) where TValue : class
        {
            Contract.Assume(!string.IsNullOrWhiteSpace(url));
            var json = JsonHelper.ObjectToJson(body);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            _client.DefaultRequestHeaders.Accept.Clear();
            _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var responseMsg = await _client.PostAsync(url, content);
            var data = await responseMsg.Content.ReadAsStringAsync();
            return data;
        }
        public async Task<string> PostForm<TValue>(TValue body, string url, string name = "http") where TValue:class
        {
            Contract.Assume(!string.IsNullOrWhiteSpace(url));
            _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
            var content = new MultipartFormDataContent();
            body.GetType().GetProperties().Where(x => x.GetValue(body) != null && !string.IsNullOrWhiteSpace(x.GetValue(body).ToString()))
                .OrderBy(x => x.Name).ToList().ForEach(x =>
                {
                    var str = x.GetValue(body).ToString();
                    content.Add(new StringContent(str), x.Name);
                });
            var responseMsg = await _client.PostAsync(url, content);
            var data = await responseMsg.Content.ReadAsStringAsync();
            return data;
        }
        public async Task<string> Get(string url)
        {
            Contract.Assume(!string.IsNullOrWhiteSpace(url));
            var responseMsg = await _client.GetAsync(url);
            var data = await responseMsg.Content.ReadAsStringAsync();
            return data;
        }
    }
}
